/*
 * Copyright [2008] by Edward Chang
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package per.edward.wizard.ext;

import java.awt.Component;

import javax.swing.JComponent;

import com.nexes.wizard.WizardPanelDescriptor;

/**
 * A sub-class of WizardPanelDescriptor which wraps Wizard panel with customized
 * widgets, than adds it to card manager.<BR>
 * It also provides support for WizardDataMap record, you may use the dataMap_
 * field variable to store variables you want to tranfer to other Wizard pages.
 * 
 * @author xzhang
 * 
 */
public class CustomDescriptor extends WizardPanelDescriptor {

    private WizardPanelWrapper wrapper_ = new AbstractWizardPanelWrapper();

    private Object nextPanelDescriptor_ = FINISH;

    private Object backPanelDescriptor_ = null;

    /**
     * Default constructor.
     */
    public CustomDescriptor() {
        super();
    }

    /**
     * A convenient constructor for creating a Wizard Descriptor in one step. <BR>
     * This would use default wrapper to wrap provided Wizard page.<BR>
     * If want to use a customized wrapper, please call default constructor and
     * then set your customized wrapper.
     * 
     * @param id
     * @param panel
     */
    public CustomDescriptor(Object id, Component panel) {
        setPanelDescriptorIdentifier(id);
        setWrappedPanelComponent(panel);
    }

    /**
     * A convenient constructor, all in one!
     * 
     * @param id
     * @param panel
     * @param nextPanelDescriptor
     * @param backPanelDescriptor
     * @param wrapper
     */
    public CustomDescriptor(Object id, Component panel,
            Object backPanelDescriptor, Object nextPanelDescriptor,
            WizardPanelWrapper wrapper) {
        setPanelDescriptorIdentifier(id);
        setWizardPanelWrapper(wrapper);
        setWrappedPanelComponent(panel);
        setNextPanelDescriptor(nextPanelDescriptor);
        setBackPanelDescriptor(backPanelDescriptor);
    }

    @Override
    public Object getNextPanelDescriptor() {
        return nextPanelDescriptor_;
    }

    @Override
    public Object getBackPanelDescriptor() {
        return backPanelDescriptor_;
    }

    /**
     * Here you can set the next wizard page descriptor.
     * 
     * @param nextPanelDescriptor
     */
    public void setNextPanelDescriptor(Object nextPanelDescriptor) {
        nextPanelDescriptor_ = nextPanelDescriptor;
    }

    /**
     * Here you can set the back wizard page descriptor.
     * 
     * @param backPanelDescriptor
     */
    public void setBackPanelDescriptor(Object backPanelDescriptor) {
        backPanelDescriptor_ = backPanelDescriptor;
    }

    /**
     * User can use this convenient method to wrap component panel with a
     * wrapper and then add to card manager. <BR>
     * Actually, it's the default method be called when adding a component panel
     * in CustomDescriptor. <BR>
     * Anyway, if insist to add an un-wrapped panel, you may call
     * setComponentPanel() directly.
     * 
     * @param panel
     */
    public void setWrappedPanelComponent(Component panel) {
        setPanelComponent(wrapper_.wrap(panel));
    }

    /**
     * Provides an interface for making customized wrapper.
     * 
     * @author xzhang
     * 
     */
    public static interface WizardPanelWrapper {
        public WizardPanelProblemDisplayer wrap(final Component comp);
    }

    /**
     * You may set a customized wrapper by this method call.
     * 
     * @param wrapper
     */
    public void setWizardPanelWrapper(WizardPanelWrapper wrapper) {
        if (wrapper != null)
            wrapper_ = wrapper;
    }

    public void setProblem(int level, String message) {
        WizardPanelProblemDisplayer problemDisplayer = (WizardPanelProblemDisplayer) getPanelComponent();
        problemDisplayer.setProblem(null, level, message);
        getWizard().setNextFinishButtonEnabled(false);
    }

    public void clearProblem() {
        WizardPanelProblemDisplayer problemDisplayer = (WizardPanelProblemDisplayer) getPanelComponent();
        problemDisplayer.clear();
        getWizard().setNextFinishButtonEnabled(true);
    }

    public Object[] getWizardDataMap() {
        return dataMap_.toArray();
    }

    protected WizardDataMap dataMap_ = new WizardDataMap();
}
